package com.mr3chi.horoscopes;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import com.google.android.gms.ads.AdRequest;
import com.google.android.gms.ads.AdView;
import com.mr3chi.horoscopes.R;
import com.nhaarman.listviewanimations.swinginadapters.AnimationAdapter;
import com.nhaarman.listviewanimations.swinginadapters.prepared.AlphaInAnimationAdapter;
import com.nhaarman.listviewanimations.swinginadapters.prepared.SwingBottomInAnimationAdapter;
import com.nhaarman.listviewanimations.swinginadapters.prepared.SwingLeftInAnimationAdapter;
import com.nhaarman.listviewanimations.swinginadapters.prepared.SwingRightInAnimationAdapter;
import com.todddavies.components.progressbar.ProgressWheel;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.AsyncTask;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.util.LruCache;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;

public class FragmentTodayNews extends Fragment{
	
	public static enum LoadMode {ONLINE, OFFLINE};
	
	private TodayNewsAdapter mAdapter;
	private ProgressWheel 	loadBar;
	private ListView 		listView;
	private NewsLoadingTask loader = null;
	private NewsParser 		parser = null;
	private Button 			btExpand;
	
	private List<News> offlineData;
	private LoadMode loadmode;

	private AlertDialog dialog;
	
	private int numofNews;
	private List<String> newsPage;
	
	public FragmentTodayNews() {
		
	}
	
	private BroadcastReceiver br;
	
	private void receivedBroadcast(Intent i) {
		if(((ActivityMain)getActivity()).hasConnection()){
			if(loadmode == LoadMode.OFFLINE){
				if(!dialog.isShowing()){
					dialog.show();
				}
			}
		}
    }

	@Override
	public void onPause() {
		super.onPause();
		getActivity().unregisterReceiver(br);
	}

	@Override
	public void onResume() {
		super.onResume();
		IntentFilter iff = new IntentFilter();
		iff.addAction("android.net.conn.CONNECTIVITY_CHANGE");
		getActivity().registerReceiver(br, iff);
	}

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		View rootView = inflater.inflate(R.layout.fragment_todaynews, container, false);

		parser = new NewsParser();
		loadBar = (ProgressWheel) rootView.findViewById(R.id.pw_spinner);
		loadBar.spin();
		
		offlineData = new ArrayList<News>();
		
		br = new BroadcastReceiver() {
			
			@Override
			public void onReceive(Context context, Intent intent) {
				FragmentTodayNews.this.receivedBroadcast(intent);
			}
		};
		
		AlertDialog.Builder builder = new Builder(getActivity());
		builder.setTitle(R.string.receiver_has_internet_title);
		builder.setMessage(R.string.receiver_has_internet_summary);
		builder.setPositiveButton(R.string.dialog_yes, new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				CheckConnection();
			}

		});
		builder.setNegativeButton(R.string.dialog_no, new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				return;
			}
		});
		dialog = builder.create();
		
		listView = (ListView) rootView.findViewById(R.id.todaynews_listview);
		
		View footerView = inflater.inflate(R.layout.expand_button, listView, false);
		btExpand = (Button) footerView.findViewById(R.id.expand_button);
		btExpand.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				expandNews();
			}
		});
		listView.addFooterView(footerView);
		listView.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id) {
				if(((ActivityMain)getActivity()).hasConnection()){
					Intent i = new Intent(getActivity(), ActivityNews.class);
					
					News temp = (News)mAdapter.getItem(position);
					
					i.putExtra(ActivityNews.ARG_TITLE, 	temp.getTitle());
					i.putExtra(ActivityNews.ARG_LINK, 	temp.getLink());
					i.putExtra(ActivityNews.ARG_DATE, 	temp.getShowOffString());
					i.putExtra(ActivityNews.ARG_PAGEID, temp.getPageId());
					startActivity(i);
				}else{
					Toast.makeText(getActivity(), getActivity().getResources().getString(R.string.error_no_intenet_connection), Toast.LENGTH_SHORT).show();
				}
				
			}
			
		});
		
		mAdapter = new TodayNewsAdapter(getActivity());
		
		SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
		String strAni = settings.getString("setting_effect", "0");
		int intAni = Integer.parseInt(strAni);
		
		AnimationAdapter aniAdapter;
		switch(intAni){
		case 1:
			aniAdapter = new AlphaInAnimationAdapter(mAdapter);
			break;
		case 2:
			aniAdapter = new SwingLeftInAnimationAdapter(mAdapter);
			break;
		case 3:
			aniAdapter = new SwingRightInAnimationAdapter(mAdapter);
			break;
		default:
			aniAdapter = new SwingBottomInAnimationAdapter(mAdapter);
			break;
		}
		
		aniAdapter.setInitialDelayMillis(300);
		aniAdapter.setAbsListView(listView);
		listView.setAdapter(aniAdapter);
		
		String strnumofnews = settings.getString("setting_numofnews", "10");
		numofNews = Integer.parseInt(strnumofnews);
		
		newsPage = new ArrayList<String>();
		boolean boolHP = settings.getBoolean("setting_webpage_huffingtonpost", false);
		if(boolHP){
			newsPage.add(WebPage.HUFFINGTONPOST);
		}

		CheckConnection();  
		
        return rootView;
	}
	
	public void CheckConnection() {
		if(((ActivityMain)getActivity()).hasConnection()){
			loadmode = LoadMode.ONLINE;
			setLoading(true);
			loader = new NewsLoadingTask(this,parser,numofNews,newsPage);
			loader.execute((Void) null);
        } else {
        	loadmode = LoadMode.OFFLINE;
        	loadNewsFromDB();
        	setLoading(false);
        }
	}
	
	private void loadNewsFromDB(){
		DBAdapter db = new DBAdapter(getActivity().getApplicationContext());
		db.open();
		List<News> news = new ArrayList<News>();
		//get all pages
		
		if(true){
			news.addAll(db.getNewsByPageId(WebPage.HUFFINGTONPOST));
		}
		
		//sort
		News temp;
		for(int i = 0; i<news.size(); i++){
			for(int j = 0; j<news.size(); j++){
				if(news.get(j).getDate().before(news.get(i).getDate())){
					temp = news.get(j);
					news.set(j, news.get(i));
					news.set(i, temp);
				}
			}
		}
		db.close();
		offlineData = news;
		expandNews();
	}
	
	private void saveNewsToDB(List<News> param){
		if(param == null) return;
		
		if(getActivity() == null){
			return;
		}
		DBAdapter db = new DBAdapter(getActivity());
		db.open();
		
		List<News> items = param;
		for(int i = 0; i < items.size(); i++){
			
			int idIndex = db.checkNewsByLink(items.get(i).getLink());
			if(idIndex >=0){
				items.get(i).setId(idIndex);
				db.updateNewsById(items.get(i));
			}else{
				db.insertNews(items.get(i));
			}
		}
		
		db.close();
	}
	
	private void expandNews(){
		if(loadmode == LoadMode.ONLINE){
			if(!((ActivityMain)getActivity()).hasConnection()){
				Toast.makeText(getActivity(), R.string.error_no_intenet_connection, Toast.LENGTH_SHORT).show();
				return;
			}
			btExpand.setEnabled(false);
			loader = new NewsLoadingTask(this, parser, numofNews, newsPage);
			loader.execute((Void) null); 
		}else{
			if(offlineData.size() == 0){
				Toast.makeText(getActivity(), R.string.error_no_news, Toast.LENGTH_SHORT).show();
				return;
			}
			SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
			String strnumofnews = settings.getString("setting_numofnews", "10");
			try {
				int numofnews = Integer.parseInt(strnumofnews);
				for(int i = 0; i<numofnews; i++){
					if(offlineData.size()>0){
						mAdapter.addData(offlineData.get(0));
						offlineData.remove(0);
					}else{
						break;
					}
				}
				mAdapter.notifyDataSetChanged();
			} catch (Exception e) {
			}
		}
	}
	
	private static class TodayNewsAdapter extends BaseAdapter{
		private final Context mContext;
		private final LruCache<String, Bitmap> mMemoryCache;
		private List<News> data;
		
		public TodayNewsAdapter(final Context context){
			mContext = context;
			data = new ArrayList<News>();
			
			final int cacheSize = (int) (Runtime.getRuntime().maxMemory() / 1024);
			mMemoryCache = new LruCache<String, Bitmap>(cacheSize) {
				@Override
				protected int sizeOf(final String key, final Bitmap bitmap) {
					return bitmap.getRowBytes() * bitmap.getHeight() / 1024;
				}
			};
		}
		
		public void setData(List<News> data){
			this.data = data;
		}
		
		public void addData(News news){
			this.data.add(news);
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {

			ViewHolder viewHolder;
			View view = convertView;
			if (view == null) {
				view = LayoutInflater.from(mContext).inflate(R.layout.item_todaynews, parent, false);
				viewHolder = new ViewHolder();
				view.setTag(viewHolder);
				
				viewHolder.title 		= (TextView) view.findViewById(R.id.todaynews_title);
				viewHolder.thumbnail 	= (ImageView) view.findViewById(R.id.todaynews_thumbnail);			
				viewHolder.desc 		= (TextView) view.findViewById(R.id.todaynews_desc);
			} else {
				viewHolder = (ViewHolder) view.getTag();
			}

			viewHolder.title.setText(data.get(position).getTitle());
			viewHolder.desc.setText(data.get(position).getDesc());
			setImageView(viewHolder, data.get(position).getImage());
			return view;
			
		}
		
		private void setImageView(final ViewHolder viewHolder, final String url) {		

			Bitmap bitmap = getBitmapFromMemCache(url);
			if (bitmap == null) {
				viewHolder.thumbnail.setVisibility(View.GONE);
			}else{
				viewHolder.thumbnail.setVisibility(View.VISIBLE);
				viewHolder.thumbnail.setImageBitmap(bitmap);
				
			}
		}
		
		private void addBitmapToMemoryCache(final String key, final Bitmap bitmap) {
			if (getBitmapFromMemCache(key) == null) {
				mMemoryCache.put(key, bitmap);
			}
		}

		private Bitmap getBitmapFromMemCache(final String key) {
			return mMemoryCache.get(key);
		}

		private static class ViewHolder {
			TextView 	title;
			ImageView 	thumbnail;
			TextView 	desc;
		}

		@Override
		public int getCount() {
			return data.size();
		}

		@Override
		public Object getItem(int position) {
			return data.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}
	}
	
	public void setLoading(boolean load){
		if(load){
			if(loadBar.getVisibility()==View.VISIBLE && listView.getVisibility() == View.GONE) return;
			else{
				loadBar.setVisibility(View.VISIBLE);
				listView.setVisibility(View.GONE);
				loadBar.spin();
			}
		}else{
			if(loadBar.getVisibility()==View.GONE && listView.getVisibility() == View.VISIBLE) return;
			else{
				loadBar.setVisibility(View.GONE);
				listView.setVisibility(View.VISIBLE);
				loadBar.stopSpinning();
			}
		}
	}

	public class NewsLoadingTask extends AsyncTask<Void, Void, List<News>>{
		private FragmentTodayNews 	parent;
		private NewsParser 			parser;
		private int					numOfNews;
		private List<String> 		pageList;
		
		
		public NewsLoadingTask(FragmentTodayNews parent, NewsParser parser, int numofPage, List<String> pageList) {
			this.parent = parent;
			this.parser = parser;
			this.numOfNews = numofPage;
			this.pageList = pageList;
		}
		
		@Override
		protected List<News> doInBackground(Void... params) {
			try {
				parser.parseNext(numOfNews,pageList);
				
			} catch (IOException e) {
				return null;
			}
			return parser.getCombinedNewsList();
		}

		@Override
		protected void onPreExecute() {
			super.onPreExecute();
			parent.setLoading(true);
		}

		@Override
		protected void onPostExecute(List<News> result) {
			super.onPostExecute(result);
			if(result == null){
				Toast.makeText(parent.getActivity(), R.string.error_parsing_failed, Toast.LENGTH_SHORT).show();
			}else if(result.size() == 0){
				Toast.makeText(parent.getActivity(), R.string.error_parsing_but_nothing, Toast.LENGTH_SHORT).show();
			}else{
				saveNewsToDB(result);
				mAdapter.setData(result);
				mAdapter.notifyDataSetChanged();
			}
			parent.setLoading(false);
			if(!btExpand.isEnabled()){
				btExpand.setEnabled(true);
			}
		}

		@Override
		protected void onCancelled() {
			super.onCancelled();
			loader = null;
			parent.setLoading(false);
		}
	}
	
}
